﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.ComponentModel.DataAnnotations;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.Linq;

namespace TP_02.Models
{

    public class Game
    {

        [Key]
        public int Id { get; set; }

        [Required]
        public string Name { get; set; }

        [Required]
        [Range(1, 6)]
        [DisplayName("Rating")]
        public Rating GameRating { get; set; }

        [Required]
        [Range(1, int.MaxValue)]
        [DisplayName("Category")]
        public int CategoryId { get; set; }

        [Required]
        public string Developer { get; set; }

        public static List<Game> GetList()
        {
            using (var cnx = new SqlConnection(
                    ConfigurationManager.ConnectionStrings["TP_02"].ConnectionString))
            {

                const string requete = "SELECT * FROM [Game]";
                var cmd = new SqlCommand(requete, cnx) { CommandType = CommandType.Text };

                try
                {
                    cnx.Open();
                    var games = new List<Game>();
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            var game = new Game
                            {
                                Id = (int) reader["Id"],
                                Name = (string) reader["Name"],
                                GameRating = (Rating) (int) reader["Rating"],
                                CategoryId = (int) reader["CategoryId"],
                                Developer = (string) reader["Developer"]
                            };
                            games.Add(game);
                        }
                    }
                    return games;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    return null;
                }
            }
        }

        public static Game FindOne(int id)
        {
            using (var cnx = new SqlConnection(
                    ConfigurationManager.ConnectionStrings["TP_02"].ConnectionString))
            {

                var requete = "SELECT * FROM [Game] WHERE Id = " + id;
                var cmd = new SqlCommand(requete, cnx) { CommandType = CommandType.Text };

                try
                {
                    cnx.Open();
                    Game game = null;
                    using (var reader = cmd.ExecuteReader())
                    {
                        while (reader.Read())
                        {
                            game = new Game
                            {
                                Id = (int) reader["Id"],
                                Name = (string) reader["Name"],
                                GameRating = (Rating) (int) reader["Rating"],
                                CategoryId = (int) reader["CategoryId"],
                                Developer = (string) reader["Developer"]
                            };
                        }
                    }
                    return game;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    return null;
                }
            }
        }

        public static bool Destroy(int id)
        {
            using (var cnx = new SqlConnection(
                    ConfigurationManager.ConnectionStrings["TP_02"].ConnectionString))
            {

                var requete = "DELETE FROM [Game] WHERE Id = " + id;
                var cmd = new SqlCommand(requete, cnx) { CommandType = CommandType.Text };

                try
                {
                    cnx.Open();
                    cmd.ExecuteNonQuery();
                    cnx.Close();
                    return true;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    return false;
                }
            }
        }

        public bool SaveAsNew()
        {
            const string requete = "INSERT INTO [Game] (Name, Rating, CategoryId,"
                                   + "Developer) VALUES (@Name, @Rating,"
                                   + "@CategoryId,@Developer);";
            return DefaultCommand(requete);
        }

        public bool Update()
        {
            var requete = "UPDATE [Game] SET "
                          + "Name=@Name,"
                          + "Rating=@Rating,"
                          + "CategoryId=@CategoryId,"
                          + "Developer=@Developer "
                          + "WHERE Id = " + Id;
            return DefaultCommand(requete);
        }

        private bool DefaultCommand(string requete)
        {
            using (var cnx = new SqlConnection(
                    ConfigurationManager.ConnectionStrings["TP_02"].ConnectionString))
            {

                var cmd = new SqlCommand(requete, cnx) { CommandType = CommandType.Text };

                cmd.Parameters.Add("Name", SqlDbType.NVarChar);
                cmd.Parameters.Add("Rating", SqlDbType.Int);
                cmd.Parameters.Add("CategoryId", SqlDbType.Int);
                cmd.Parameters.Add("Developer", SqlDbType.NVarChar);

                cmd.Parameters["Name"].SqlValue = Name;
                cmd.Parameters["Rating"].SqlValue = (int) GameRating;
                cmd.Parameters["CategoryId"].SqlValue = CategoryId;
                cmd.Parameters["Developer"].SqlValue = Developer;

                try
                {
                    cnx.Open();
                    cmd.ExecuteNonQuery();
                    cnx.Close();
                    return true;
                }
                catch (Exception e)
                {
                    Debug.WriteLine(e.Message);
                    Debug.WriteLine(e.StackTrace);
                    return false;
                }
            }
        }

        public static Dictionary<int, string> GetRatingDictionary()
        {
            var dict = Enum.GetValues(typeof(Rating)).Cast<Rating>().ToDictionary(t => (int) t, t => t.ToString());
            dict.Add(0, "Choose a Rating");
            return dict;
        }
    }

    public enum Rating
    {
        Child = 1,
        Everyone = 2,
        Everyone10 = 3,
        Teen = 4,
        Mature = 5,
        Adult = 6
    }

    public enum Platform
    {
        Windows = 1,
        Osx = 1 << 1,
        Linux = 1 << 2,
        Playstation = 1 << 3,
        Xbox = 1 << 4,
        Ios = 1 << 5,
        Android = 1 << 6
    }
}